/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import tubes5progin.client.folderstructure.filesystem;

/**
 *
 * @author Rezha
 */
public class directoryHelper {

    //variable
    public File file;

    public directoryHelper(File f) {
        this.file = f;
    }

    public String[] getListDirectory() {
        return this.file.list();
    }

    public List<File> getDirectoryOnly() {
        List<File> temp = new LinkedList<File>();
        String[] list = getListDirectory();
        for (String s : list) {
            File f = new File(this.file.getAbsolutePath() + "\\" + s);
            if (f.isDirectory()) {
                temp.add(f);
            }
        }
        return temp;
    }

    public List<File> getDirectoryOnly(File f) {
        List<File> tempFile = new LinkedList<File>();
        String[] list = f.list();
        for (String s : list) {
            File temp = new File(f.getAbsolutePath() + "\\" + s);
            if (f.isDirectory()) {
                tempFile.add(f);
            }
        }
        return tempFile;
    }

    public List<File> getFilesOnly() {
        List<File> temp = new LinkedList<File>();
        String[] list = getListDirectory();
        for (String s : list) {
            File f = new File(this.file.getAbsolutePath() + "\\" + s);
            if (f.isFile()) {
                temp.add(f);
            }
        }
        return temp;
    }

    public List<File> getFilesOnly(File f) {
        List<File> tempFile = new LinkedList<File>();
        String[] list = f.list();
        for (String s : list) {
            File temp = new File(f.getAbsolutePath() + "\\" + s);
            if (f.isFile()) {
                tempFile.add(temp);
            }
        }
        return tempFile;
    }

    public filesystem getListFileSystem() {
        if (this.file.isDirectory()) {
            filesystem fs = new filesystem(this.file);
            //dapatkan list direktori dan file
            List<File> currentDir = getDirectoryOnly();
            List<File> currentFiles = getFilesOnly();
            //masukkan filenya terlebih dahulu
            for (File f : currentFiles) {
                fs.addFiles(f);
            }
            //masukkan direktorynya
            for (File f : currentDir) {
                fs.addDirectory(new directoryHelper(f).getListFileSystem());
            }
            return fs;
        }
        return null;
    }

    public void createAllDirs(filesystem diff, String rootDir) {
        for (filesystem f : diff.directory) {
            //cek apakah folder tersebut sudah ada ato belum
            File temp = new File(rootDir + "\\" + f.parentDir.getName());
            if (!temp.isDirectory()) {
                temp.mkdir();
            }
            createAllDirs(f, rootDir + "\\" + f.parentDir.getName());
        }
    }

    public static byte[] getBytesFromFile(File file) throws IOException {
        InputStream is = new FileInputStream(file);

        // Get the size of the file
        long length = file.length();

        if (length > Integer.MAX_VALUE) {
            // File is too large
        }

        // Create the byte array to hold the data
        byte[] bytes = new byte[(int) length];

        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length
                && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file " + file.getName());
        }

        // Close the input stream and return bytes
        is.close();
        return bytes;
    }

    public static void writeByteToFile(byte[] b, String path) {
        try {
            FileOutputStream fos = new FileOutputStream(path);
            fos.write(b);
            fos.close();
        } catch (IOException ex) {
            Logger.getLogger(directoryHelper.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public static byte[] toBytes(Object object) {
        java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
        try {
            java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(baos);
            oos.writeObject(object);
        } catch (java.io.IOException ioe) {
            java.util.logging.Logger.global.log(java.util.logging.Level.SEVERE,
                    ioe.getMessage());
        }

        return baos.toByteArray();
    }

    public static Object toObject(byte[] bytes) {
        Object object = null;
        try {
            object = new java.io.ObjectInputStream(new java.io.ByteArrayInputStream(bytes)).readObject();
        } catch (java.io.IOException ioe) {
            java.util.logging.Logger.global.log(java.util.logging.Level.SEVERE,
                    ioe.getMessage());
        } catch (java.lang.ClassNotFoundException cnfe) {
            java.util.logging.Logger.global.log(java.util.logging.Level.SEVERE,
                    cnfe.getMessage());
        }
        return object;
    }

    // <editor-fold defaultstate="collapsed" desc="BackUp Fungsi-Fungsi ga jelas">
    //fungsi untuk membandingkan dua filesystem misal getdiff(server,client) berarti dapatkan semua file di server yang harus di download oleh client
    public static filesystem getFileSystemDifferent(filesystem fs1, filesystem fs2) {
        filesystem ret = new filesystem();
        //dapatkan file parent nya
        ret.parentDir = fs1.parentDir;
        //file dolo
        for (File f : fs1.files) {
            //cek apakah ada di fs2
            File temp;
            if ((temp = isContainsFile(f, fs2.files)) != null) {
                if (temp == f) {
                    ret.files.add(f);
                }
            } else {
                //ret.addFiles(f);
            }
        }
        //trus directory
        for (filesystem fs : fs1.directory) {
            filesystem temp;
            //berarti ada direktori di server yang namanya sama dengan di client
            if ((temp = isContains(fs, fs2.directory)) != null) {
                ret.addDirectory(getFileSystemDifferent(fs, temp));
            } else {
                //kalo ga ada, tambahin aja
                ret.addDirectory(fs);
            }
        }
        return ret;
    }

    private static filesystem isContains(filesystem fs, List<filesystem> directory) {
        for (filesystem temp : directory) {
            if (fs.parentDir.getName().equals(temp.parentDir.getName())) {
                return temp;
            }
        }
        return null;
    }

    public static File isContainsFile(File f, List<File> list) {
        for (File f2 : list) {
            //cek namanya
            if (f2.getName().equals(f.getName())) {
                //kalo sama cek size nya
                if (f2.length() != f.length()) {
                    //kalo tidak sama,
                    return getNewerFile(f2, f);
                } else {
                    return null;
                }
            }
        }
        return f;
    }

    public static boolean isContainsFileBiasa(File f,List<File> list){
         for (File f2 : list) {
            //cek namanya
            if (f2.getName().equals(f.getName())) {
                //kalo sama cek size nya
                return true;
            }
        }
        return false;
    }

    public static boolean isContainsDirBiasa(filesystem fs,List<filesystem> list){
         for (filesystem f2 : list) {
            //cek namanya
            if (f2.parentDir.getName().equals(fs.parentDir.getName())) {
                //kalo sama cek size nya
                return true;
            }
        }
        return false;
    }

    public static File getNewerFile(File f1, File f2) {
        if (f1.lastModified() > f2.lastModified()) {
            return f1;
        }
        return f2;
    }

    public List<String> getListFile(filesystem diff, String rootdir) {
        List<String> temp = new LinkedList<String>();
        //ambil filenya
        for (File f : diff.files) {
            if (rootdir.equals("")) {
                temp.add(f.getName());
            } else {
                temp.add(rootdir+"\\"+f.getName());
            }
        }
        //trus direktorinya
        for(filesystem fs : diff.directory){
            if(rootdir.equals(""))
                temp.addAll(getListFile(fs, fs.parentDir.getName()));
            else
                temp.addAll(getListFile(fs, rootdir+"\\"+fs.parentDir.getName()));
        }
        return temp;
    }

    public List<String> deletedFilesAndDir(filesystem currentfs,filesystem prevFs,String rootdir){
        List<String> ret = new LinkedList<String>();
        for(File f: prevFs.files){
            if(!isContainsFileBiasa(f, currentfs.files)){
                if(rootdir.equals(""))
                    ret.add(f.getName());
                else
                    ret.add(rootdir+"\\"+f.getName());
            }
        }
        //trus dapatkan isi direktornya
        for(filesystem fs : prevFs.directory){
            if(!isContainsDirBiasa(fs, currentfs.directory)){
                if(rootdir.equals(""))
                    ret.add(fs.parentDir.getName());
                else
                    ret.add(rootdir+"\\"+fs.parentDir.getName());
            }else{
                //ret.addAll(deletedFilesAndDir(fs, currentfs.directory.g, rootdir));
            }
        }
        return ret;
    }

    // </editor-fold>
}
